﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharp.Libs.ExceptionHandling;


namespace CSharp.Libs.Koc
{
    public class URLHolder
    {
        #region declarations
        //basic references
        private ExceptionCollector _EC = null;

        //url references
        private URLItem _urlMainSrc = null;
        private URLItem _urlFetchMapTiles = null;
        private URLItem _urlViewCourt = null;
        private URLItem _urlGetChat = null;
        private URLItem _urlAllianceGetOtherInfo = null;
        private URLItem _urlGetUserLeaderboard = null;
        private URLItem _urlGetOnline = null;
        private URLItem _urlMyServers = null;
        private URLItem _urlMarch = null;
        private URLItem _urlUpdateSeed = null;
        private URLItem _urlListReports = null;
        private URLItem _urlFetchReport = null;
        private URLItem _urlDeleteCheckedReports = null;

        #region constants
        #region php commands
        public const String PHP_MAIN_SRC =                      "main_src.php";
        public const String PHP_FETCH_MAP_TILES =               "fetchMapTiles.php";
        public const String PHP_VIEW_COURT =                    "viewCourt.php";
        public const String PHP_GET_CHAT =                      "getChat.php";
        public const String PHP_ALLIANCE_GET_OTHER_INFO =       "allianceGetOtherInfo.php";
        public const String PHP_GET_USER_LEADERBOARD =          "getUserLeaderboard.php";
        public const String PHP_GET_ONLINE =                    "getOnline.php";
        public const String PHP_MY_SERVERS =                    "myServers.php";
        public const String PHP_MARCH =                         "march.php";
        public const String PHP_UPDATE_SEED =                   "updateSeed.php";
        public const String PHP_LIST_REPORTS =                  "listReports.php";
        public const String PHP_FETCH_REPORT =                  "fetchReport.php";
        public const String PHP_DELETE_CHECKED_REPORTS =        "deleteCheckedReports.php";
        #endregion

        #region common parameters
        public const String PARAM_FB_SIG =                      "fb_sig";
        public const String PARAM_FB_SIG_ADDED =                "fb_sig_added";
        public const String PARAM_FB_SIG_API_KEY =              "fb_sig_api_key";
        public const String PARAM_FB_SIG_APP_ID =               "fb_sig_app_id";
        public const String PARAM_FB_SIG_BASE_DOMAIN =          "fb_sig_base_domain";
        public const String PARAM_FB_SIG_COOKIE_SIG =           "fb_sig_cookie_sig";
        public const String PARAM_FB_SIG_COUNTRY =              "fb_sig_country";
        public const String PARAM_FB_SIG_EXPIRES =              "fb_sig_expires";
        public const String PARAM_FB_SIG_EXT_PERMS =            "fb_sig_ext_perms";
        public const String PARAM_FB_SIG_IN_IFRAME =            "fb_sig_in_iframe";
        public const String PARAM_FB_SIG_IN_NEW_FACEBOOK =      "fb_sig_in_new_facebook";
        public const String PARAM_FB_SIG_LOCALE =               "fb_sig_locale";
        public const String PARAM_FB_SIG_PROFILE_UPDATE_TIME =  "fb_sig_profile_update_time";
        public const String PARAM_FB_SIG_SESSION_KEY =          "fb_sig_session_key";
        public const String PARAM_FB_SIG_SS =                   "fb_sig_ss";
        public const String PARAM_FB_SIG_TIME =                 "fb_sig_time";
        public const String PARAM_FB_SIG_USER =                 "fb_sig_user";
        public const String PARAM_KABAM_UID =                   "kabamuid";
        public const String PARAM_LANG =                        "lang";
        public const String PARAM_STANDALONE =                  "standalone";
        public const String PARAM_TP_UID =                      "tpuid";
        public const String PARAM_TV_UID =                      "tvuid";
        public const String PARAM_SIGNED_REQUEST =              "signed_request";
        public const String PARAM_PF =                          "pf";
        #endregion
        
        #region command specific parameters
        //common comamnd parameters
        public const String PARAM_PAGE_NO =                     "pageNo";

        //getChat.php
        public const String PARAM_CTYPE =                       "ctype";
        public const String PARAM_CTYPE_ID =                    "ctypeId";
        public const String PARAM_CUR_NEWEST_1 =                "curNewest1";
        public const String PARAM_CUR_NEWEST_2 =                "curNewest2";
        public const String PARAM_CUR_NEWEST_3 =                "curNewest3";
        public const String PARAM_SID =                         "sid";

        //allianceGetOtherInfo.php
        public const String PARAM_CITY_ID =                     "cityId";

        //getUserLeaderboard.php
        public const String PARAM_ALLIANCE_ID =                 "allianceId";
        public const String PARAM_PER_PAGE =                    "perPage";

        //viewCourt.php
        public const String PARAM_PID =                         "pid";

        //getOnline.php
        public const String PARAM_CHECK_ARR =                   "checkArr";

        //march.php
        public const String PARAM_CID =                         "cid";
        public const String PARAM_TYPE =                        "type";
        public const String PARAM_KID =                         "kid";
        public const String PARAM_X_COORD =                     "xcoord";
        public const String PARAM_Y_COORD =                     "ycoord";
        public const String PARAM_GOLD =                        "gold";
        public const String PARAM_R1 =                          "r1";
        public const String PARAM_R2 =                          "r2";
        public const String PARAM_R3 =                          "r3";
        public const String PARAM_R4 =                          "r4";
        public const String PARAM_ITEMS =                       "items";

        //updateSeed.php
        public const String PARAM_FORCE_UPDATE =                "forceUpdate";

        //listReports.php
        //common parameter pageNo
        public const String PARAM_GROUP =                       "group";

        //fetchReport.php
        public const String PARAM_RID =                         "rid";
        public const String PARAM_SIDE =                        "side";

        //deleteCheckedReports.php
        public const String PARAM_CITY_RIDS =                   "cityrids";
        public const String PARAM_S0_RIDS =                     "s0rids";
        public const String PARAM_S1_RIDS =                     "s1rids";
        #endregion
        #endregion
        #endregion



        #region constructor / terminator
        public URLHolder(
            ExceptionCollector EC)
        {
            _EC = EC;

            _urlMainSrc = new URLItem(_EC);
            _urlFetchMapTiles = new URLItem(_EC);
            _urlViewCourt = new URLItem(_EC);
            _urlGetChat = new URLItem(_EC);
            _urlAllianceGetOtherInfo = new URLItem(_EC);
            _urlGetUserLeaderboard = new URLItem(_EC);
            _urlGetOnline = new URLItem(_EC);
            _urlMyServers = new URLItem(_EC);
            _urlMarch = new URLItem(_EC);
            _urlUpdateSeed = new URLItem(_EC);
            _urlListReports = new URLItem(_EC);
            _urlFetchReport = new URLItem(_EC);
            _urlDeleteCheckedReports = new URLItem(_EC);
        }

        ~URLHolder()
        {
            _urlDeleteCheckedReports = null;
            _urlFetchReport = null;
            _urlListReports = null;
            _urlUpdateSeed = null;
            _urlMarch = null;
            _urlMyServers = null;
            _urlGetOnline = null;
            _urlGetUserLeaderboard = null;
            _urlAllianceGetOtherInfo = null;
            _urlGetChat = null;
            _urlViewCourt = null;
            _urlFetchMapTiles = null;
            _urlMainSrc = null;

            _EC = null;
        }
        #endregion



        #region private functions
        #region URL parsing
        private Boolean _ParseURLMainSrc(
            String URL)
        {
            try
            {
                _urlMainSrc.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_MAIN_SRC))
                {
                    _urlMainSrc = _GetURLItem(URL);
                    return _urlMainSrc.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLFetchMapTiles(
        String URL)
        {
            try
            {
                _urlFetchMapTiles.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_FETCH_MAP_TILES))
                {
                    _urlFetchMapTiles = _GetURLItem(URL);
                    return _urlFetchMapTiles.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLViewCourt(
            String URL)
        {
            try
            {
                _urlViewCourt.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_VIEW_COURT))
                {
                    _urlViewCourt = _GetURLItem(URL);
                    return _urlViewCourt.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLGetChat(
            String URL)
        {
            try
            {
                _urlGetChat.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_GET_CHAT))
                {
                    _urlGetChat = _GetURLItem(URL);
                    return _urlGetChat.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLAllianceGetOtherInfo(
            String URL)
        {
            try
            {
                _urlAllianceGetOtherInfo.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_ALLIANCE_GET_OTHER_INFO))
                {
                    _urlAllianceGetOtherInfo = _GetURLItem(URL);
                    return _urlAllianceGetOtherInfo.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLGetUserLeaderboard(
            String URL)
        {
            try
            {
                _urlGetUserLeaderboard.Reset();

                if(_IsFacebookURL(URL) &&
                    URL.Contains(PHP_GET_USER_LEADERBOARD))
                {
                    _urlGetUserLeaderboard = _GetURLItem(URL);
                    return _urlGetUserLeaderboard.URLMaybeValid;
                }
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLGetOnline(
            String URL)
        {
            try
            {
                _urlGetOnline.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_GET_ONLINE))
                {
                    _urlGetOnline = _GetURLItem(URL);
                    return _urlGetOnline.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLMyServers(
            String URL)
        {
            try
            {
                _urlMyServers.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_MY_SERVERS))
                {
                    _urlMyServers = _GetURLItem(URL);
                    return _urlMyServers.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLMarch(
            String URL)
        {
            try
            {
                _urlMarch.Reset();

                if(_IsFacebookURL(URL) &&
                    URL.Contains(PHP_MARCH))
                {
                    _urlMarch = _GetURLItem(URL);
                    return _urlMarch.URLMaybeValid;
                }
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLUpdateSeed(
            String URL)
        {
            try
            {
                _urlUpdateSeed.Reset();

                if (_IsFacebookURL(URL) &&
                    URL.Contains(PHP_UPDATE_SEED))
                {
                    _urlUpdateSeed = _GetURLItem(URL);
                    return _urlUpdateSeed.URLMaybeValid;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLListReports(
            String URL)
        {
            try
            {
                _urlListReports.Reset();

                if(_IsFacebookURL(URL) &&
                    URL.Contains(PHP_LIST_REPORTS))
                {
                    _urlListReports = _GetURLItem(URL);
                    return _urlListReports.URLMaybeValid;
                }
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLFetchReport(
            String URL)
        {
            try
            {
                _urlFetchReport.Reset();

                if(_IsFacebookURL(URL) &&
                    URL.Contains(PHP_FETCH_REPORT))
                {
                    _urlFetchReport = _GetURLItem(URL);
                    return _urlFetchReport.URLMaybeValid;
                }
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }

        private Boolean _ParseURLDeleteCheckedReports(
            String URL)
        {
            try
            {
                _urlDeleteCheckedReports.Reset();

                if(_IsFacebookURL(URL) &&
                    URL.Contains(PHP_DELETE_CHECKED_REPORTS))
                {
                    _urlDeleteCheckedReports = _GetURLItem(URL);
                    return _urlDeleteCheckedReports.URLMaybeValid;
                }
            }
            catch(Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }
        #endregion

        #region URLItem creation
        /// <summary>_GetURLItem
        /// 
        /// </summary>
        /// <param name="URL"></param>
        /// <returns></returns>
        private URLItem _GetURLItem(
            String URL)
        {
            URLItem UI = new URLItem(_EC);

            try
            {
                String[] strURLParts = URL.Split('?');

                if (strURLParts.Count() == 2)
                {
                    UI.CommandPHP = strURLParts[0];
                    UI.Parameters = _GetParameterDictionary(strURLParts[1]);
                }

                if (UI.Parameters.Count >= 2)
                {
                    UI.URLMaybeValid = true;
                }
                else
                {
                    UI.Reset();
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return UI;
        }

        /// <summary>_IsFacebookURL
        /// 
        /// </summary>
        /// <param name="URL"></param>
        /// <returns></returns>
        private Boolean _IsFacebookURL(
            String URL)
        {
            try
            {
                if (URL.Contains("facebook.com") ||
                    URL.Contains("fb_sig") ||
                    URL.Contains("fbml_sessionkey"))
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return false;
        }
        #endregion

        /// <summary>_GetParameterDictionary</summary>
        /// <param name="PostParameters"></param>
        /// <returns></returns>
        /// <history>modified 14.10.2011: There was an error when a parameter was double</history>
        private Dictionary<String, String> _GetParameterDictionary(
            String PostParameters)
        {
            Dictionary<String, String> dicParameters = new Dictionary<String, String>();

            try
            {
                String[] strParameters = PostParameters.Split('&');

                foreach (String STR in strParameters)
                {
                    String[] strParametersValues = STR.Split('=');

                    if (strParametersValues.Count() == 2)
                    {
                        //14.10.2011: See if a parameter already exists, otherwise there's an error.
                        if (!dicParameters.ContainsKey(strParametersValues[0]))
                        {
                            dicParameters.Add(strParametersValues[0], strParametersValues[1]);
                        }
                        else
                        {
                            dicParameters[strParametersValues[0]] = strParametersValues[1];
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }

            return dicParameters;
        }

        /// <summary>_SetNewServerId
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <history>07.04.2011</history>
        private void _SetNewServerId(
            Int32 value)
        {
            try
            {
                _urlMainSrc.CommandPHPServerId = value;
                _urlFetchMapTiles.CommandPHPServerId = value;
                _urlViewCourt.CommandPHPServerId = value;
                _urlGetChat.CommandPHPServerId = value;
                _urlAllianceGetOtherInfo.CommandPHPServerId = value;
                _urlGetUserLeaderboard.CommandPHPServerId = value;
                _urlGetOnline.CommandPHPServerId = value;
                _urlMyServers.CommandPHPServerId = value;
            }
            catch (Exception ex)
            {
                _EC.AddException(ex, this.ToString(), _EC.Tools.GetCurrentMethodName());
            }
        }
        #endregion



        #region interface
        #region properties
        public URLItem URLMainSrc
        {
            get
            {
                return _urlMainSrc;
            }
        }

        public URLItem URLFetchMapTiles
        {
            get
            {
                return _urlFetchMapTiles;
            }
        }

        public URLItem URLViewCourt
        {
            get
            {
                return _urlViewCourt;
            }
        }

        public URLItem URLGetChat
        {
            get
            {
                return _urlGetChat;
            }
        }

        public URLItem URLAllianceGetOtherInfo
        {
            get
            {
                return _urlAllianceGetOtherInfo;
            }
        }

        public URLItem URLGetUserLeaderboard
        {
            get
            {
                return _urlGetUserLeaderboard;
            }
        }

        public URLItem URLGetOnline
        {
            get
            {
                return _urlGetOnline;
            }
        }

        public URLItem URLMyServers
        {
            get
            {
                return _urlMyServers;
            }
        }

        public URLItem URLMarch
        {
            get
            {
                return _urlMarch;
            }
        }

        public URLItem URLUpdateSeed
        {
            get
            {
                return _urlUpdateSeed;
            }
        }

        public URLItem URLListReports
        {
            get
            {
                return _urlListReports;
            }
        }

        public URLItem URLFetchReport
        {
            get
            {
                return _urlFetchReport;
            }
        }

        public URLItem URLDeleteCheckedReports
        {
            get
            {
                return _urlDeleteCheckedReports;
            }
        }
        #endregion

        #region methods
        public void SetNewServerId(
            Int32 value)
        {
            _SetNewServerId(value);
        }

        public Dictionary<String, String> GetParameterDictionary(
            String PostParameters)
        {
            return _GetParameterDictionary(PostParameters);
        }

        public Boolean ParseURLMainSrc(
            String URL)
        {
            return _ParseURLMainSrc(URL);
        }

        public Boolean ParseURLFetchMapTiles(
            String URL)
        {
            return _ParseURLFetchMapTiles(URL);
        }

        public Boolean ParseURLViewCourt(
            String URL)
        {
            return _ParseURLViewCourt(URL);
        }

        public Boolean ParseURLGetChat(
            String URL)
        {
            return _ParseURLGetChat(URL);
        }

        public Boolean ParseURLAllianceGetOtherInfo(
            String URL)
        {
            return _ParseURLAllianceGetOtherInfo(URL);
        }

        public Boolean ParseURLGetUserLeaderboard(
            String URL)
        {
            return _ParseURLGetUserLeaderboard(URL);
        }

        public Boolean ParseURLGetOnline(
            String URL)
        {
            return _ParseURLGetOnline(URL);
        }

        public Boolean ParseURLMyServers(
            String URL)
        {
            return _ParseURLMyServers(URL);
        }

        public Boolean ParseURLMarch(
            String URL)
        {
            return _ParseURLMarch(URL);
        }

        public Boolean ParseURLUpdateSeed(
            String URL)
        {
            return _ParseURLUpdateSeed(URL);
        }

        public Boolean ParseURLListReports(
            String URL)
        {
            return _ParseURLListReports(URL);
        }

        public Boolean ParseURLFetchReport(
            String URL)
        {
            return _ParseURLFetchReport(URL);
        }

        public Boolean ParseURLDeleteCheckedReports(
            String URL)
        {
            return _ParseURLDeleteCheckedReports(URL);
        }
        #endregion
        #endregion
    }
}
